package com.wlin.leaf.utils;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.util.List;

/**
 * Copyright (c) 2010-3020 Zhongshan Pole 3D Electronic Tech. Co., Ltd. All Rights Reserved.
 * <p>
 * This software is the confidential and proprietary information of
 * Zhongshan Pole 3D Electronic Tech. You shall not disclose such Confidential Information
 * and shall use it only in accordance with the terms of the agreements
 * you entered into with Zhongshan Pole 3D Electronic Tech.
 * <p>
 * 项目名称：diyhome-parent
 * 类名称：ZkClient
 * 类描述： ${DESCRIPTION}
 *
 * @author wlin
 * @version 1.0
 * @since 2018/9/25
 */
public class ZkClientTools {

    private CuratorFramework zkClient;

    private String zookeeperHost;

    public ZkClientTools(String zookeeperHost) {
        this.zookeeperHost = zookeeperHost;
    }

    //@PostConstruct
    public void postConstruct() {
        if(zookeeperHost == null || "".equals(zookeeperHost)){
            throw new IllegalStateException("必须配置zookeeperHost");
        }
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        this.zkClient = CuratorFrameworkFactory.newClient(zookeeperHost, retryPolicy);
        zkClient.start();
    }

    //@PreDestroy
    public void preDestroy() {
        if(zkClient != null) {
            zkClient.close();
        }
    }

    public String createNode(CreateMode mode, String path, byte[] data ) throws Exception {
        return zkClient.create().creatingParentsIfNeeded().withMode(mode).forPath(path,data);
    }

    public String createNode(CreateMode mode, String path) throws Exception {
        return zkClient.create().creatingParentsIfNeeded().withMode(mode).forPath(path);
    }

    public ChildrenNodesStat getChildren(String parent) throws Exception {
        if(zkClient.checkExists().forPath(parent) != null) {
            List<String> nodes = zkClient.getChildren().forPath(parent);
            return this.new ChildrenNodesStat(nodes);
        }
        return null;
    }

    public CuratorFramework getClient() {
        return zkClient;
    }

    public class ChildrenNodesStat{

        List<String> nodes ;

        public ChildrenNodesStat(List<String> nodes) {
            this.nodes = nodes;
        }

        public String getNodeStartWith(String prefix) {
            for (String node : nodes) {
                if(node.startsWith(prefix)){
                    return node;
                }
            }
            return null;
        }

        public Stat getNodeStatStartWith(String prefix) throws Exception {
            String node = getNodeStartWith(prefix);
            if(node != null){
                return zkClient.checkExists().forPath(node);
            }
            return null;
        }

        public boolean hasNodeStartWith(String prefix) {
            for (String node : nodes) {
                if(node.startsWith(prefix)){
                    return true;
                }
            }
            return false;
        }

        public List<String> getNodes() {
            return nodes;
        }
    }

    public static class Builder{
        public static ZkClientTools build(String zkHost){
            ZkClientTools zkClientTools = new ZkClientTools(zkHost);
            zkClientTools.postConstruct();
            return zkClientTools;
        }
    }
}